' Copyright (c) Microsoft Corporation.  All rights reserved.
Imports System
Imports System.Collections.Generic
Imports System.Data
Imports System.Data.Common
Imports System.Data.EntityClient
Imports System.Data.Metadata.Edm
Imports System.Linq
Imports System.Runtime.CompilerServices

Namespace EdmMetadataHelpersVB
    ''' <summary>
    ''' This class allows an EntityDataReader to be hydrated into a DataTable
    ''' </summary>
    ''' <remarks></remarks>
    Public Class EdmDataReaderAdapter
        ''' <summary>
        ''' Used to lookup EdmType to ClrType mappings
        ''' </summary>
        ''' <remarks></remarks>
        Private Shared _oc As ObjectItemCollection = New ObjectItemCollection()

        ''' <summary>
        ''' Creates a column of the right type and size for the field
        ''' </summary>
        Protected Shared Function ConvertToColumn(ByVal field As FieldMetadata) As DataColumn
            Dim type As EdmType = field.FieldType.TypeUsage.EdmType

            'Work out the clr type associated with the EdmType
            Dim clrTypes = From p In _oc.GetPrimitiveTypes() _
                          Where p.GetEdmPrimitiveType().FullName = type.FullName _
                          Select p.ClrEquivalentType

            Dim clrType = clrTypes.FirstOrDefault()

            'If there is no clr type we can't create a column either
            If clrType Is Nothing Then
                Return Nothing
            End If

            Dim column As New DataColumn(field.FieldType.Name, clrType)


            ' Use the fields TypeUsage facets to see if there is a maxlength
            ' for any string columns
            If clrType Is GetType(String) Then
                Dim maxLength = GetFacet(field, "MaxLength")
                column.MaxLength = CType(maxLength.Value, Integer)
            End If

            Return column

        End Function
        ''' <summary>
        ''' Get a Facet by name from a fields metadata
        ''' </summary>
        Protected Shared Function GetFacet(ByVal field As FieldMetadata, ByVal name As String) As Facet
            Dim facet As Facet = Nothing
            field.FieldType.TypeUsage.Facets.TryGetValue(name, True, facet)
            Return facet
        End Function
        ''' <summary>
        ''' Creates an empty DataTable shaped so that records described by the DataRecordInfo
        ''' can be stored in the DataTable
        ''' </summary>
        Public Shared Function LoadSchema(ByVal info As DataRecordInfo) As DataTable
            Dim table As New DataTable(info.RecordType.EdmType.FullName)

            Dim columns = From field In info.FieldMetadata _
                          Select ConvertToColumn(field)


            Dim available = From column In columns _
                            Where column IsNot Nothing

            For Each column In available
                table.Columns.Add(column)
            Next


            Return table
        End Function

        ''' <summary>
        ''' Creates and Loads a DataTable from an EntityDataReader
        ''' </summary>
        Public Shared Function LoadTable(ByVal reader As EntityDataReader) As DataTable
            Dim table As DataTable

            table = LoadSchema(reader.DataRecordInfo)
            table.FillWith(reader.Enumerate())

            Return table
        End Function
    End Class
End Namespace

